package com.dalonedrow.engine.sprite.base;

import java.util.Comparator;

import com.dalonedrow.engine.systems.Sprite;
import com.dalonedrow.pooled.PooledStringBuilder;
import com.dalonedrow.pooled.StringBuilderPool;

/**
 * Comparator for the {@link SpriteBase} class.
 * @author Donald
 */
public final class SpriteComparator implements Comparator<SpriteBase> {
	/**
	 * Creates a new instance of SpriteComparator.
	 */
	public SpriteComparator() { }
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int compare(final SpriteBase s0, final SpriteBase s1) {
		PooledStringBuilder buff =
				StringBuilderPool.getInstance().getStringBuilder();
		buff.append("comparing sprites ");
		final int invalid = -999;
		int val = invalid;
		SimpleVector3 v0 = s0.getPosition();
		SimpleVector3 v1 = s1.getPosition();
		int t0 = Sprite.getInstance().getTextureId(s0);
		int t1 = Sprite.getInstance().getTextureId(s1);
		// do they even have coordinates?
		if (v0 == null
				&& v1 == null) {
			val = 0;
		} else if (v0 == null
				&& v1 != null) {
			val = 1;
		} else if (v0 != null
				&& v1 == null) {
			val = -1;
		}
		if (val == invalid) {
			// are they on the same z-plane?
			if (v0.getZ() < v1.getZ()) {
				// v0 is below v1, and is rendered first
				val = -1;
			} else if (v0.getZ() > v1.getZ()) {
				// v0 is above v1, and is rendered last
				val = 1;
			} else { // same z-plane
				if (v0.getX() > v1.getX()) {
					// v0 is to the right of v1
					if (v0.getY() > v1.getY()) {
						// v0 is higher than v1, and is rendered first
						val = -1;
					} else if (v0.getY() < v1.getY()) {
						// v0 is lower than v1, and is rendered last
						val = 1;
					} else {
						// v0 is to the right of v1, but on the
						// same y-plane, v1 is rendered first
						val = -1;
					}
				} else if (v0.getX() < v1.getX()) {
					// v0 is to the left of v1
					if (v0.getY() > v1.getY()) {
						// v0 is higher than v1, and is rendered first
						val = -1;
					} else if (v0.getY() < v1.getY()) {
						// v0 is lower than v1, and is rendered last
						val = 1;
					} else {
						// v0 is to the left of v1, but on the
						// same y-plane, v0 is rendered last
						val = 1;
					}
				} else {
					// v0 is on the same x-plane as v1
					if (v0.getY() > v1.getY()) {
						// v0 is higher than v1, and is rendered first
						val = -1;
					} else if (v0.getY() < v1.getY()) {
						// v0 is lower than v1, and is rendered last
						val = 1;
					} else {
						// v0 and v1 are on the same x, y, and z plane.
						// sort by texture
						if (t0 == t1) {
							val = 0;
						} else if (t0 < t1) {
							val = -1;
						} else {
							val = 1;
						}
					}
				}
			}
		}	
		buff.returnToPool();
		return val;
	}
}
